#ifndef __FILTER_H__
#define __FILTER_H__

#include <vector>

#include "Image.h" // alleen voor die stomme BorderInfo

void convertFloatToUnsignedChar(const pip::Image<float> &input, pip::Image<unsigned char> &output);
void convertUnsignedCharToFloat(const pip::Image<unsigned char> &input, pip::Image<float> &output);

float linearInterpolation(const pip::Image<float> &image, const float &x, const float &y);

void filter(const pip::Image<float> &input, pip::Image<float> &output, const pip::Image<float> &mask, const pip::BorderInfo &bi = pip::border_mirror);
void filterSeparable(const pip::Image<float> &in, pip::Image<float> &out, const std::vector<std::vector<float> > &kernels, const pip::BorderInfo &bi = pip::border_mirror);

float g0(const int &i, const float &sigma);
float g1(const int &i, const float &sigma);
float g2(const int &i, const float &sigma);
float g3(const int &i, const float &sigma);

void normalize(std::vector<float> &kernel);

void gauss(const pip::Image<float> &in, pip::Image<float> &out, const float &sigma, const int &dx = 0, const int &dy = 0, const float &cutoff = 5.0, const pip::BorderInfo &bi = pip::border_mirror);

// Return minimum and maximum of the input image
template <class T>
void getMinMaxImage(const pip::Image<T> &in, T &min, T &max)
{
  min = numeric_limits<T>::max();
  max = numeric_limits<T>::min();

  for (int z = 0; z < in.dim(2); ++z) {
    for (int y = 0; y < in.dim(1); ++y) {
      for (int x = 0; x < in.dim(0); ++x) {
        T value(in(x, y, z));

        if (value > max) {
          max = value;
        }

        if (value < min) {
          min = value;
        }
      }
    }
  }
}
#endif